Inventing on Principle

0:00 · [박수] 앞선 세션과 달리, 저는 나눠드릴 상품이 없습니다.
0:11 · 저는 그냥 여러분이 인생을 어떻게 살아야 하는지에 대해 이야기하려고 합니다.
0:14 · 사실 이번 강연은 대부분의 사람들이 잘 이야기하지 않는 인생을 살아가는 한 가지 방식에 대한 것입니다.
0:21 · 여러분이 커리어를 쌓아가면서 열정을 따르라거나 좋아하는 일을 하라는 말을 많이 듣게 될 것입니다.
0:30 · 저는 조금 다른 이야기를 하려고 합니다.
0:33 · 저는 '원칙'을 따르는 것에 관해 이야기할 것입니다.
0:37 · 여러분의 일에서 이정표가 되어줄 원칙, 즉 여러분이 중요하고 필요하며 옳다고 믿는 무언가를 찾고, 그것을 여러분이 하는 일의 길잡이로 삼는 것에 대해서 말이죠.
0:46 · 이 강연은 세 부분으로 나뉩니다. 먼저 제 작업의 많은 부분에 길잡이가 되어주는 원칙에 대해 말씀드리겠습니다.
0:51 · 그리고 그 원칙에서 어떤 결과물이 나오는지 맛보여 드리겠습니다.
0:54 · 마지막으로 이런 방식으로 살아온 다른 사람들은 어떤 원칙을 가졌고, 무엇을 믿었는지 이야기해 보려 합니다.
1:01 · 하지만 이 모든 것은 여러분이 무엇을 믿고, 인생을 어떻게 살아가고 싶은지 생각해보는 데 도움을 주기 위한 예시일 뿐입니다.
1:08 · 우선 제 이야기부터 시작하자면, 저에게는 '아이디어'가 매우 중요합니다.
1:15 · 저는 세상에 아이디어를 내놓는 것이 인간이 하는 가장 중요한 일 중 하나라고 생각합니다.
1:21 · 그리고 위대한 예술, 이야기, 발명품, 과학 이론의 형태를 띤 위대한 아이디어들은 그 자체로 생명력을 얻으며, 인간으로서 우리의 삶에 의미를 부여한다고 생각합니다.
1:35 · 그래서 저는 사람들이 어떻게 아이디어를 창조하고 아이디어가 어떻게 성장하는지, 특히 어떤 종류의 도구가 아이디어가 자라나기에 건강한 환경을 만드는지에 대해 많이 고민합니다.
1:46 · 저는 수년 동안 창작 도구를 만들고, 창작 도구를 사용하고, 이에 대해 깊이 생각하며 많은 시간을 보냈습니다. 그리고 마침내 깨닫게 된 원칙이 있습니다.
1:56 · 창작자는 자신이 만드는 대상과 즉각적으로 연결되어야 합니다.
2:01 · 이것이 바로 저의 원칙입니다.
2:02 · 창작자는 자신이 창조하는 것과 즉각적인 연결이 필요합니다.
2:06 · 이 말의 의미는 무언가를 만들 때, 어떤 변경을 가하거나 결정을 내렸다면 그 효과를 즉시 볼 수 있어야 한다는 뜻입니다.
2:14 · 어떠한 지연도 없어야 하고, 숨겨진 것이 있어서도 안 됩니다.
2:18 · 창작자는 자신이 무엇을 하고 있는지 볼 수 있어야 합니다.
2:20 · 이제 이 원칙이 무너진 사례들을 보여드리고, 제가 그 문제를 어떻게 해결했는지 보여드리겠습니다.
2:27 · 그러고 나서 제가 이 일을 하는 더 큰 맥락에 관해 이야기하겠습니다.
2:33 · 우선, 코딩(프로그래밍)에 대해 생각해 봅시다.
2:35 · 코딩은 보통 이런 식으로 작동합니다.
2:37 · 텍스트 에디터에 코드 뭉치를 타이핑하면서, 각 줄의 코드가 무엇을 할지 머릿속으로 상상합니다.
2:44 · 그런 다음 컴파일하고 실행하면 무언가 결과물이 나옵니다.
2:47 · 이 경우에는 자바스크립트가 캔버스에 나무가 있는 작은 풍경을 그려내는 화면입니다.
2:54 · 하지만 이 풍경에 문제가 있거나, 변경하고 싶거나, 더 좋은 아이디어가 떠오르면 다시 코드로 돌아가야 합니다.
3:01 · 코드를 수정하고, 컴파일하고, 실행해서 결과가 어떤지 확인합니다.
3:07 · 문제가 있으면 다시 코드로 돌아갑니다.
3:08 · 제 시간의 대부분은 텍스트 에디터 안에서 코드를 만지며 보냅니다. 제가 실제로 만들고자 하는 대상인 '화면'과의 즉각적인 연결 없이, 보이지 않는 상태로 맹목적으로 작업하는 것이죠.
3:20 · 그래서 저는 이것이 창작자와 창작물 사이에 즉각적인 연결이 필요하다는 제 원칙에 위배된다고 느낍니다.
3:26 · 그래서 제 원칙에 더 부합할 수 있는 코딩 환경을 고안해 보려고 노력했습니다.
3:34 · 여기 보시는 화면은 한쪽에는 그림이 있고, 다른 한쪽에는 코드가 있습니다. 이 부분은 하늘을 그리고, 이 부분은 산을, 이 부분은 나무를 그립니다.
3:47 · 코드를 조금만 변경해도 옆의 그림이 즉시 바뀝니다.
3:52 · 이처럼 코드와 그림은 언제나 실시간으로 동기화됩니다.
3:54 · 컴파일하고 실행하는 과정이 없습니다.
3:56 · 그저 코드에서 뭔가를 바꾸면, 그림에서 바로 바뀌는 것이 보입니다.
4:02 · 이제 코드와 그림 사이에 즉각적인 연결이 생겼으니, 텍스트를 직접 타이핑하는 것 외에 코드를 바꾸는 다른 방법들을 생각해 볼 수 있습니다. 예를 들어, 여기 있는 숫자는 나뭇가지의 길이입니다. 이 숫자를 조절하고 싶다면, 마우스를 올려두고 컨트롤(Ctrl) 키를 누른 채 드래그하여 값을 올리거나 내릴 수 있습니다. 나뭇가지가 길어지거나 짧아질 때 어떤 모습인지 바로 확인할 수 있고, 예술적으로 제 마음에 쏙 드는 지점으로 수렴해 갈 수 있습니다. 코드에 있는 어떤 숫자든 이 방식으로 조절할 수 있습니다. 마우스로 가리키고 값을 올리거나 내리기만 하면 됩니다. 어떤 숫자들은 무슨 역할을 하는지 알고 있지만, 실제로 바뀌는 모습을 보면 여전히 놀랍습니다.
4:42 · 그리고 어떤 숫자들은 완전히 예상치 못한 결과를 보여주기도 합니다.
4:49 · 아래를 보시면 16까지 세어주는 'for 루프(반복문)'가 있습니다.
4:53 · 가지마다 16개의 작은 분홍색 꽃송이를 달아주는 코드입니다.
4:56 · 이 숫자를 내려서 꽃을 적게 만들 수도 있고, 올려서 더 많게 만들 수도 있습니다.
5:00 · 그런데 제가 지금 여기서 무엇을 하고 있는지 보세요.
5:03 · 그저 숫자를 20 근처에서 위아래로 움직이고 있을 뿐입니다.
5:07 · 그런데 아주 흥미롭게 일렁이는 효과가 나타납니다.
5:09 · 마치 나무 사이로 바람이 불어오는 것처럼 보이죠.
5:13 · 이 모습을 처음 보았을 때, 저는 즉시 이 효과를 애니메이션에 어떻게 활용할 수 있을까 고민하기 시작했습니다.
5:20 · 만약 매번 코드를 바꿀 때마다 컴파일하고 실행해야 했다면, 제가 과연 이런 현상을 발견이나 할 수 있었을까요?
5:25 · 예술의 많은 부분, 창작의 많은 부분은 '발견'이며, 자신이 무엇을 하고 있는지 볼 수 없다면 아무것도 발견할 수 없습니다.
5:32 · 지금까지는 코드를 수정하는 모습을 보여드렸으니, 이제 코드를 추가해 보겠습니다.
5:35 · 여기 하늘에 태양을 하나 띄우고 싶습니다. 그래서 '하늘 그리기(draw sky)' 함수 끝으로 가서 원을 채우는 코드를 넣으려고 합니다. context.fillCircle이라고 타이핑을 시작하자마자, 사용할 수 있는 다양한 채우기(fill) 메서드 목록이 자동 완성으로 나타납니다.
5:50 · fillCircle, fillRect, fillText 등 타이핑할 수 있는 여러 선택지가 나오는데, 이 자동 완성 목록을 위아래로 움직일 때마다 각각의 코드가 무엇을 하는지 화면에 즉시 나타납니다.
6:01 · 따라서 메서드 이름만 보고 그것이 무엇을 할지 머릿속으로 상상할 필요가 없습니다.
6:05 · 문서를 찾아볼 필요도 없습니다.
6:07 · 그냥 보입니다. 즉시 보입니다.
6:10 · 제가 원하는 건 이 원입니다.
6:12 · 그리고 X 좌표와 Y 좌표를 조정해 보겠습니다.
6:16 · 반지름도 변경합니다.
6:18 · 이 정도면 적당해 보이네요.
6:22 · 노란색이어야 할 것 같습니다.
6:23 · 채우기 스타일을 설정하겠습니다.
6:25 · context.fillStyle
6:27 · 이전과 같은 방식으로 모델을 저장하고,
6:29 · 채우기 스타일을 선택합니다.
6:30 · 기본값으로 흰색이 주어지네요.
6:32 · 이 색상 코드 역시 다른 숫자들과 마찬가지 방식으로 바꿀 수 있습니다.
6:37 · 컨트롤 키를 누르면 컬러 팔레트가 나타납니다.
6:42 · 제 태양에 어울리는 예쁜 노란색을 고를 수 있습니다.
6:48 · 하지만 흰색도 나름대로 흥미롭다는 생각이 드네요.
6:52 · 전혀 예상하지 못했는데, 흰색으로 두니 이제 태양이 아니라 달처럼 보이죠, 그렇죠?
6:59 · 어라, 밤이 되었네요.
7:01 · [웃음] 이처럼 즉각적인 연결을 갖추는 것은, 이전에는 불가능했던 방식으로 아이디어가 표면으로 드러나고 발전할 수 있게 해줍니다.
7:12 · 하지만 여기에는 여전히 문제가 하나 있다고 생각합니다. 여기에 그림이 있고 저기에 코드가 있는데, 이 둘 사이의 매핑(연결 관계)을 제 머릿속으로 계속 유지해야 한다는 점입니다.
7:26 · 코드가 이렇게 많은데, 그냥 이 한 줄만 봐서는 이것이 정확히 무슨 일을 하는지 즉각적으로 알 수 없습니다.
7:33 · 이럴 때 저는 이렇게 할 수 있습니다.
7:34 · 옵션(Option) 키를 누릅니다.
7:36 · 커서가 돋보기 모양으로 바뀝니다.
7:38 · 이제 코드의 각 줄 위로 마우스를 가져가면, 해당 코드가 그림에서 어느 부분을 그리고 있는지 하이라이트(강조)되어 표시됩니다.
7:46 · 이 함수 안에서 무슨 일이 일어나는지 알고 싶다면, 그냥 함수를 따라 마우스를 내리며 어디가 하이라이트되는지 보기만 하면 됩니다.
7:56 · 여기 산을 그리는 함수(draw mountain)를 두 번 호출하는 코드가 있습니다. 어느 것이 어느 산인지 모를 때, 마우스를 대보면 아, 이건 저 산이고, 저건 그 산이구나 알 수 있습니다.
8:02 · 그리고 반대 방향으로도 작동해야 합니다. 즉, 그림의 특정 부분을 보았을 때 이를 그린 책임이 있는 코드가 무엇인지 알 수 있어야 합니다.
8:09 · 똑같이 하면 됩니다.
8:10 · 옵션 키를 누른 채로 말이죠.
8:12 · 이제 그림의 각 픽셀 위로 마우스를 움직이면, 오른쪽 코드 창에서 그 픽셀을 그린 코드 줄로 커서가 바로 이동하는 것을 볼 수 있습니다.
8:20 · 거기는 하늘을 그린 곳이고, 여기는 나무를 그린 곳, 저기는 꽃을 그린 곳이네요. 이것은 두 영역 사이의 매핑을 유지하는 데도 정말 중요하지만, 단순히 화면을 탐색할 때도 아주 유용합니다. 예를 들어, 태양을 조금 더 크게 만들고 싶다면 거기로 바로 점프해서 태양을 키우고, 나무를 조금 올리고 싶다면 거기로 점프해서 나무를 올리고, 산을 조금 올리고 싶다면 거기로 점프해서 산을 조금 올릴 수 있습니다. 아이디어가 떠오르는 즉시 이렇게 빠르게 변경을 적용할 수 있습니다. 그리고 무언가를 생각하는 것과 그것을 보고 발전시키는 것 사이의 피드백 루프에 지연이 없다면, 이는 창작 과정에서 대단히 중요한 일입니다. 지연이 있다면, 세상에 결코 나오지 못했을 수많은 아이디어의 세계가 존재하게 될 것입니다.
9:14 · 그것들은 우리가 미처 생각조차 할 수 없는 생각들이 되어버립니다.
9:34 · 저에게 아이디어는 매우 중요합니다.
9:36 · 아이디어의 속성은 처음에는 아주 작게 시작한다는 점입니다.
9:41 · 아주 왜소하고, 약하고, 부서지기 쉬운 상태로 시작하죠. 아이디어가 발전하고 성숙해지기 위해서는 창작자가 그것을 보살피고, 돌보고, 영양을 주며 성장을 형성할 수 있는 환경이 필요합니다. 저에게 있어 이 '즉각적인 연결'이라는 원칙의 의미가 바로 그것입니다. 아이디어는 저에게 너무나 소중하기 때문에, 이 원칙이 훼손되는 것을 볼 때, 즉 창작자가 자신이 무엇을 하고 있는지 볼 수 없어서 아이디어가 사산되거나 성장이 멈추는 것을 볼 때, 저는 그것이 잘못되었다고 느낍니다.
10:12 · UI 가이드라인을 위반했거나 모범 사례(Best Practice)에 어긋났다는 의미의 '잘못됨'이 아닙니다. 그보다 훨씬 더 깊은 차원에서 잘못되었다는 뜻입니다.
10:20 · 이 이야기로 다시 돌아오겠지만, 우선 이 원칙을 따른 또 다른 사례를 보여드리고 싶습니다.
10:25 · 여기 이 코드에는 '상태(State)'가 존재하지 않습니다.
10:28 · 지속되는 상태가 없기 때문에 시간도 없고, 상호작용(Interactivity)도 없습니다.
10:32 · 그래서 저는 제가 가진 원칙에 부합하는 방식으로 프로그래밍의 이러한 측면(시간과 상호작용)을 어떻게 다룰 수 있을지 고민했습니다. 그 원칙이란 바로 '창작자에게는 즉각적인 연결이 필요하다'는 것입니다.
10:42 · 여기 제가 만든 작은 플랫폼 게임이 있습니다. 이 작은 캐릭터가 제 주인공입니다. 이리저리 뛰어다닐 수 있죠.
10:48 · 점프도 할 수 있고, 죽을 수도 있습니다. 그리고 이 캐릭터를 움직이는 코드가 바로 여기에 있습니다. 이 코드는 캐릭터를 달리게 만들고, 이건 점프하게 만들며, 이건 다른 물체와 충돌하게 만듭니다. 그리고 이 아래쪽에는 작은 거북이를 위한 코드가 있습니다. 지금은 코드를 아직 다 쓰지 않아서 거북이가 별다른 움직임을 보이지 않는데, 지금 바로 코드를 완성해 보겠습니다. 매 틱(tick)마다 거북이의 X 좌표에 '방향 × 시간 간격(1/60초) × 속도'를 더해줍니다. 이 속도는 빠를 수도 있고 느릴 수도 있겠죠.
11:20 · 속도 값이 음수이면 거북이는 뒤로 걷습니다. 이런 아이디어들은 다른 적 캐릭터에게도 활용할 수 있겠지만, 거북이는 원래 느려야 하니까요. 이 정도가 거북이에게 딱 좋은 속도인 것 같네요. 그리고 위쪽을 보면 이런 코드가 있습니다. "주인공이 거북이와 충돌하면, Y축 속도를 얻어 공중으로 튀어 오르고 거북이는 밟혀서 납작해진다." 실행하면 이런 모습이 됩니다. 그리고 잠시 후에 거북이가 다시 일어납니다.
12:01 · 문제는, 플레이어가 아직은 이 위쪽으로 올라가지 못하게 하고 싶다는 점입니다.
12:05 · 플레이어가 거북이를 딛고 튕겨 나가서 이 아래에 있는 작은 통로로 지나가기를 원합니다.
12:10 · 주변을 돌며 퍼즐 같은 것들을 해결한 뒤에 다시 돌아와서 별을 획득해야 하는 구조죠.
12:15 · 그래서 지금은 거북이가 너무 많이 튕겨 오르게 설정되어 있습니다.
12:17 · 물론 코드에서 그 수치를 낮추고 다시 시도해 볼 수 있겠지만, 이번에는 너무 안 튕기네요.
12:26 · 게임을 멈추고, 다시 컴파일하고, 아까 있던 위치를 새로 찾을 필요 없이, 게임이 실행되는 도중에 코드를 수정할 수 있다는 점은 분명 좋습니다. 하지만 제가 정말로 확인해야 하는 것, 즉 '캐릭터가 저 점프를 성공할 수 있는지 없는지'를 즉각적으로 볼 수는 없습니다.
12:40 · 그래서 이제 제가 하려는 것은 이렇습니다.
12:42 · 거북이를 밟고 튕겨 나가는 순간 게임을 일시 정지하겠습니다.
12:46 · 게임을 멈추면 위에 슬라이더가 나타나는데, 이를 통해 시간을 뒤로 되돌릴 수(Rewind) 있습니다.
12:51 · 이제 점프하기 전으로 시간을 되돌린 다음 코드를 변경하여 튕기는 정도를 줄여보겠습니다.
13:03 · 이 상태에서 다시 시간을 앞으로 진행시키면, 이전에 기록된 것과 동일한 입력 컨트롤(키보드 명령)을 사용하되 변경된 새 코드를 적용하여 앞으로의 상황을 시뮬레이션합니다.
13:21 · 하지만 이것만으로는 충분하지 않습니다.
13:25 · 저는 변화를 '즉각적으로' 볼 수 있어야 합니다.
13:27 · 튕기는 정도가 적절한지 아닌지를 곧바로 확인할 수 있어야 합니다.
13:34 · 이런 번거로운 과정 없이 말이죠.
13:35 · 만약 시간에 따라 진행되는 프로세스가 있고 그 변화를 즉각적으로 보고 싶다면, '시간을 공간으로 매핑'해야 합니다.
13:43 · 그래서 이렇게 해보겠습니다.
13:44 · 거북이를 밟고 튕겨 나갈 때 게임을 멈추고, 주인공의 이동 궤적(Trail)을 보여주는 이 버튼을 누르겠습니다. 이제 캐릭터가 지나온 경로를 볼 수 있습니다. 그리고 시간을 되돌리면, 캐릭터 앞에 표시되는 이 궤적이 앞으로 캐릭터가 움직일 경로, 즉 '미래'가 됩니다. 그리고 제가 코드를 바꾸면, 캐릭터의 미래도 바뀝니다. 덕분에 게임을 다시 재생했을 때 캐릭터가 저 틈새로 쏙 들어갈 수 있도록 정확한 값을 찾아낼 수 있습니다.
14:16 · (청중 박수) 이처럼 창작자는 자신이 무엇을 하고 있는지 볼 수 있어야 합니다.
14:28 · 시간에 종속된(Embedded in time) 무언가를 설계할 때는 시간을 제어할 수 있어야 합니다.
14:31 · 시간을 가로질러 볼 수 있어야 합니다.
14:33 · 그렇지 않으면 눈을 감고 설계하는 것과 다름없습니다.
14:35 · 이걸 가지고 놀다 보니 중력을 조절하는 것도 재미있다는 걸 발견했습니다.
14:42 · 중력(Gravity)을 약간 음수로 만들면 캐릭터가 공중으로 떠오르기 시작합니다.
14:46 · (청중 웃음) 조절 바를 만지면서 캐릭터를 공중에 머물게 할 수도 있죠.
14:50 · 이 중력 조절 메커니즘 하나만 가지고도 게임 한 편을 통째로 만들 수도 있을 것입니다.
14:58 · 사실 이 코드의 어느 부분이든 만지다 보면 게임에 대한 아이디어가 떠오를 것 같습니다.
15:05 · 심지어 코드의 첫 번째 문장을 주석 처리하기만 해도, 이제 캐릭터는 왼쪽으로 움직이지 못합니다.
15:12 · 오직 오른쪽으로만 움직일 수 있죠.
15:16 · 다소 황당하게 들릴지 모르겠지만, 테리 캐버나(Terry Cavanagh)라는 개발자는 실제로 이 개념을 바탕으로 'Don't Look Back'이라는 아름다운 게임을 만들었습니다.
15:23 · 테리 캐버나는 여러분도 보셨을 법한 'VVVVVV'(알파벳 V를 여섯 번 쓴 제목)라는 정말 멋진 게임도 만들었습니다.
15:31 · 그 게임의 방식은 점프를 할 수 없는 대신, 방향을 반대로 뒤집어서 아래로 떨어지는 게 아니라 위로 떨어지게 만드는 것입니다.
15:40 · 그러니까 천장에 떨어져 매달리거나, 다시 바닥으로 걸어 다닐 수 있는 식이죠.
15:46 · 그래서 이런 구조의 레벨이 있다면, 이리저리 걸어 다니며 지형을 통과하는 법을 배워야 합니다.
15:56 · 만약 이런 장애물이 있다면 점프해서 넘어갈 수 없으니, 중력을 뒤집고 다시 뒤집으면서 진행해야 합니다. 이 개념 하나만으로 엄청난 양의 게임플레이를 만들어 냈죠.
16:07 · 다시 말씀드리지만, 아이디어가 떠오르는 즉시 그것을 시도해 볼 수 있어야 합니다.
16:25 · 이 예시와 방금 전 나무(Tree) 예시는 둘 다 매우 시각적인 프로그램입니다.
16:30 · 화면의 그림이 어떻게 바뀌는지 보는 것만으로도 우리가 변경한 사항을 확인할 수 있습니다.
16:33 · 그래서 저는 이 원칙에 부합하면서도, 더 추상적인 코딩을 할 수 있는 방법은 없을까 고민했습니다.
16:39 · 우리가 무엇을 하고 있는지 직접 보면서 일반적인 알고리즘을 작성하려면 어떻게 해야 할까요?
16:44 · 하나의 예로 '이진 탐색(Binary Search)'을 살펴보겠습니다.
16:48 · 이진 탐색이 어떻게 작동하는지 아주 빠르게 리마인드해 보죠.
16:51 · 정렬된 값들이 들어있는 배열이 있고, 그 배열 안에서 찾고자 하는 값인 '키(Key)'가 있습니다.
16:58 · 그리고 해당 값이 존재할 수 있는 하한선(Lower bound)과 상한선(Upper bound)을 나타내는 두 변수를 추적합니다. 지금 상태에서는 어디든 있을 수 있겠죠. 그리고 그 범위의 딱 중간을 확인합니다.
17:07 · 중간에서 찾은 값이 키보다 작다면, 키는 그 뒤에 있어야 합니다. 다시 그 범위의 중간을 확인합니다.
17:13 · 찾은 값이 너무 크다면 키는 그 앞에 있어야 하죠. 이런 식으로 범위를 계속 반으로 나누면서 찾고자 하는 값으로 좁혀나갑니다.
17:20 · 코드로 구현하면 이진 탐색은 이런 모습입니다. 하지만 제 관점에서는, 여기서는 아무것도 볼 수가 없습니다.
17:28 · 정말 아무것도 보이지 않습니다.
17:30 · 'array'라는 단어는 보이지만, 실제 배열은 보이지 않습니다.
17:34 · 그래서 이런 코드를 작성하려면 머릿속으로 배열을 상상해야 합니다.
17:38 · 본질적으로 여러분 스스로가 컴퓨터 역할을 해야 하는 것이죠. 코드의 각 줄이 컴퓨터에서 어떻게 실행될지 머릿속으로 시뮬레이션해야 합니다.
17:45 · 대개 우리가 실력 있는 소프트웨어 엔지니어라고 부르는 사람들은, 단지 이 '컴퓨터 역할'을 머릿속으로 아주 잘 수행하는 사람들일 뿐입니다.
17:52 · 그런데 컴퓨터를 사용해서 코드를 쓰고 있으면서, 왜 컴퓨터가 할 일을 우리 머릿속으로 시뮬레이션하고 있어야 할까요?
18:00 · 컴퓨터가 직접 실행해서 우리에게 보여주면 안 되는 걸까요?
18:05 · 그럼 이진 탐색을 작성해 보겠습니다.
18:08 · 함수(Function)를 만듭니다.
18:12 · 이진 탐색(Binary search) 함수는,
18:13 · 키(key)와 배열(array)을 인자로 받습니다.
18:15 · 그러면 이쪽 화면에서는 이렇게 묻습니다. "좋습니다, 키와 배열을 받는데, 구체적으로 어떤 값인가요?"
18:21 · 예시를 보여달라는 것이죠.
18:22 · 작업할 수 있는 대상을 달라는 겁니다.
18:24 · 예를 들어, 배열이 [a, b, c, d, e, f] 라고 해봅시다.
18:31 · 그리고 찾고자 하는 키 값이 'd' 라고 가정해 보겠습니다.
18:34 · 이제 코딩을 시작합니다.
18:36 · 하한선(low)은 0에서 시작합니다.
18:40 · 화면 우측에 low = 0이라고 표시됩니다. 특별할 건 없습니다.
18:43 · 상한선(high)은 배열의 끝에서 시작합니다.
18:46 · 즉, high = array.length - 1 입니다.
18:50 · 그러자 우측에 high = 5라고 뜹니다.
18:53 · 코드에는 추상적인 공식을 적었지만,
18:57 · 우측 화면은 입력된 예시 인자에 대응하는 '구체적인 값'을 실시간으로 보여줍니다.
19:03 · 덕분에 이 그림을 머릿속으로 계속 유지할 필요가 없습니다. 화면이 그냥 보여주니까요.
19:09 · 이제 배열의 중간 인덱스가 필요합니다.
19:13 · 두 값의 평균을 내보겠습니다. mid = (low + high) / 2
19:18 · 음, 이건 분명히 잘못되었네요.
19:22 · 2.5는 유효한 배열 인덱스가 아닙니다.
19:24 · 소수점을 버려야(내림)겠네요.
19:27 · 그래서 내림 함수(floor)를 추가했더니 2로 반올림(내림)되었습니다.
19:30 · 전체 함수를 다 작성하고 20개의 단위 테스트(Unit Test)를 돌려보는 대신, 코드를 타이핑한 바로 그 순간에 버그를 잡아낸 것입니다.
19:38 · 이제 배열에서 값을 가져옵니다.
19:39 · 그런 다음 범위를 좁혀야 하므로 if 문이 필요한데, 이건 그냥 복사해서 붙여넣겠습니다.
19:51 · 이 경우, 제가 찾은 값이 키보다 작습니다.
19:53 · 따라서 if 문의 첫 번째 분기(Branch)를 타게 됩니다.
19:56 · 그리고 하한선(low) 값을 조정합니다.
19:59 · 물론 키 값이 더 작았다면 다른 분기를 타서 상한선(high) 값을 조정했겠죠.
20:05 · 혹은 만약 찾으려는 키(key)가 'c'였다면, 우리는 첫 번째 시도 만에 우연히 그것을 찾아냈을 것이고, 그 인덱스(index)를 반환했을 것입니다.
20:13 · 이것이 이 알고리즘의 첫 번째 반복(iteration)입니다.
20:19 · 그리고 이제 우리가 해야 할 일은 루프(반복문)를 도는 것입니다.
20:21 · 배열을 이미 소분할해 두었으니까요.
20:22 · 우리가 찾고자 하는 것을 좁혀서 찾아낼 때까지 계속해서 소분할해야 합니다.
20:27 · 그러니 루프를 돌아야 하죠.
20:28 · 일단 이 모든 작업을 while (true) 루프로 감싸서 처리해 보겠습니다.
20:32 · 그럼 이제 이 루프의 세 번의 반복에 해당하는 세 개의 열이 생깁니다.
20:41 · 여기 첫 번째 열은 방금 전에 보셨던 것과 정확히 일치합니다.
20:44 · 하한선(low)과 상한선(high)이 배열 전체를 가리키고 있습니다.
20:46 · 'C'를 찾았지만, 값이 너무 낮았습니다.
20:49 · 그래서 하한선을 조정합니다.
20:51 · 루프는 여기까지 올라갑니다.
20:52 · 두 번째 반복에서는 범위가 더 좁혀집니다.
20:54 · 'E'를 찾았네요. 상한선을 조정합니다.
20:57 · 세 번째 반복, 루프는 여기까지 올라갑니다.
21:00 · 이제 하한선과 상한선이 같아졌습니다.
21:01 · 하나의 후보로 좁혀서 본 적이 없었던 것이죠.
21:03 · 이것이 정말 우리가 찾던 키가 맞고, 그 인덱스를 다시 반환합니다.
21:07 · 보시다시피 여기에는 숨겨진 것이 아무것도 없습니다.
21:09 · 매 순간 알고리즘이 무엇을 하고 있는지 정확히 볼 수 있죠. 그리고 여기로 올라가서 다른 키들을 시도해 보며 다양한 입력값에 따라 알고리즘이 어떻게 작동하는지 확인할 수 있습니다. 이 데이터를 훑어봄으로써 이 알고리즘이 어떻게 작동하는지에 대한 직관을 기를 수 있죠. 지금 다른 키들을 시도해 보고 있는데요, 예를 들어 'G'를 찾는다고 해봅시다. 이건 조금 다르게 보이네요. 실제로 값을 반환하지 않고 있습니다. 그 이유는 실제로 배열에 없는 키를 찾고 있기 때문입니다.
21:43 · 그리고 이 루프를 빠져나갈 수 있는 유일한 방법은 키를 찾는 것뿐입니다.
21:47 · 그래서 여기서 갇힌 채 영원히 루프를 돌고 있는 것이죠.
21:50 · 그럼 이걸 보면서 무엇이 잘못되었는지 살펴볼 수 있습니다.
21:53 · 알고리즘이 어디서부터 궤도를 벗어나고 있나요?
21:55 · 처음 몇 번의 반복은 괜찮아 보이지만, 이번 반복은 이상해 보입니다. 범위가 완전히 붕괴되어서 하한선(low)이 상한선(high)보다 커졌기 때문입니다.
22:07 · 따라서 이 지점에 도달하면, 키를 찾을 수 없다는 것을 알게 됩니다.
22:11 · 여기서 이 잘못된 조건을 발견하게 되는 것이죠.
22:12 · 저는 "아, 이건 아니지"라고 말합니다.
22:13 · 하한선은 상한선보다 작거나 같아야 합니다.
22:16 · 좋습니다, 그럼 이 내용을 제 while 문의 조건으로 집어넣겠습니다.
22:18 · low <= high (하한선이 상한선보다 작거나 같을 때까지)
22:21 · 그렇게 하면 루프를 빠져나가게 될 것입니다.
22:23 · 그리고 키를 찾을 수 없다는 것을 나타내는 어떤 센티넬(sentinel, 특수 값)을 반환하겠죠.
22:27 · 자, 이제 루프가 세 번 반복되었습니다.
22:29 · 찾을 수 없었습니다.
22:30 · '찾지 못함'을 뜻하는 값을 반환합니다.
22:33 · 안대를 쓰지 않고 알고리즘을 짜는 것은 바로 이런 느낌일 것입니다.
22:37 · [박수] 다시 말씀드리지만, 저에게는 창작자가 자신이 무엇을 하고 있는지 볼 수 있어야 하고, 자신이 만드는 것과 '직관적인 연결(media connection)'이 필요하다는 원칙이 있습니다.
22:53 · 그리고 세 가지 코딩 예시를 통해 이 원칙을 보여드리려고 노력했는데요, 하지만 이건 여기가 소프트웨어 엔지니어링 콘퍼런스이고 제가 프로그래밍에 대해 이야기해야 한다고 생각했기 때문일 뿐입니다.
23:02 · 하지만 저에게 이 원칙은 특별히 프로그래밍에만 국한된 것이 아닙니다.
23:07 · 그것은 모든 종류의 창작 활동과 관련이 있습니다.
23:10 · 그래서 제가 생각하는 이 개념의 스펙트럼이 얼마나 넓은지 보여드리기 위해 데모를 몇 개 더 보여드리고 싶습니다.
23:15 · 우선, 다른 공학 분야를 살펴보겠습니다.
23:20 · 여기 제가 그린 전자 회로가 있습니다.
23:24 · 아직 다 그리지는 못했으니, 마저 마무리해 보겠습니다.
23:31 · 1.2.
23:33 · 이제 작동하는 회로가 완성되었습니다.
23:37 · 제 말은, 작동하는 회로라고 '추측'한다는 것입니다.
23:38 · 실제로 여기서 작동하고 있는 모습은 아무것도 보이지 않으니까요.
23:42 · 이것은 정적인 표현 속에서 작업하는 코딩과 정확히 똑같습니다.
23:46 · 하지만 우리가 실제로 신경 쓰는 것은 데이터, 즉 변수의 값들입니다.
23:50 · 그리고 여기서는 그것들을 볼 수 없죠.
23:52 · 회로에서 변수는 이 다양한 전선들의 전압입니다.
23:57 · 각각의 전선은 시간에 따라 변하는 전압을 가지고 있고, 우리는 그것을 볼 수 있어야 합니다. 만약 제가 이 회로를 실험실 벤치 위에서 물리적으로 직접 만들고 있었다면, 최소한 오실로스코프를 가져와 여기저기 찔러보면서 서로 다른 전선에서, 즉 여기나 저기서 무슨 일이 일어나고 있는지 볼 수 있었을 것입니다. 그러니 최소한 그 정도는 할 수 있어야 합니다. 그래서 여기 제가 준비한 것은 이 전선의 전압이 시간에 따라 어떻게 변하는지 보여주는 그래프입니다. 전압이 높아졌다, 낮아졌다, 높아졌다, 낮아졌다 하는 것을 볼 수 있으니 이건 명백히 진동(oscillating)하고 있습니다. 만약 이것을 물리적으로 만들었다면, 회로가 무언가 동작하는 모습을 실제로 볼 수 있었을 것입니다.
24:31 · 이 경우에는 위에 LED 두 개가 있습니다.
24:34 · 이것들은 LED, 그러니까 전등인데, 아마도 어떤 이유가 있어서 저기 있는 것이겠죠.
24:38 · '재생(play)'을 누르면 실시간으로 시뮬레이션되는 모습을 지켜볼 수 있습니다.
24:42 · 이제 회로가 무엇을 하고 있는지 보실 수 있습니다.
24:51 · 이와 같은 회로를 설계하려면 모든 전선의 전압을 이해해야 합니다.
24:56 · 회로 전체에서 모든 전압이 어떻게 변하는지 이해해야 하죠.
25:01 · 코딩과 마찬가지로, 환경이 그것을 여러분에게 보여주거나, 아니면 여러분이 머릿속으로 시뮬레이션을 돌려야 합니다.
25:07 · 그리고 제 머리는 전자가 무엇을 하고 있는지 시뮬레이션하는 것보다 더 좋은 일에 쓰고 싶습니다.
25:11 · 그래서 저는 이 요소들을 조금 넓게 펼쳐보겠습니다.
25:14 · 같은 회로이지만, 조금 넓게 펼친 것입니다.
25:17 · 그리고 모든 노드(node)의 전압을 추가하겠습니다.
25:20 · 이제 회로 전체의 모든 전압을 볼 수 있습니다.
25:24 · 심지어 재생을 눌러서 이 모든 것이 실시간으로 시뮬레이션되는 과정을 지켜볼 수도 있습니다.
25:29 · 하지만 제가 더 선호하는 방식은 그냥 마우스를 그 위에 올려놓는 것입니다. 그러면 제가 관심 있는 영역을 살펴보며 그 값이 얼마인지 볼 수 있죠.
25:40 · 어떤 두 노드든 서로 비교할 수 있습니다.
25:42 · 예를 들어 제가 이 노드 위에 마우스를 올리는 동안 저쪽에 있는 노드를 보시면, 제가 마우스를 올린 노드의 그림자가 저 노드 위에 겹쳐서 표시되는 것을 볼 수 있습니다.
25:49 · 사실 제가 마우스를 올린 노드의 그림자는 모든 노드 위에 겹쳐서 나타납니다.
25:52 · 그래서 그중 하나에 마우스를 올리고 다른 하나를 바라보는 것만으로 어떤 두 노드든 비교할 수 있습니다.
25:59 · 그리고 이번에도, 제가 변경한 결과가 즉각적으로 나타나는 것을 볼 수 있습니다.
26:04 · 여기 70K 옴짜리 저항이 있습니다.
26:06 · 이 값을 바꾸고 싶다면, 그냥 클릭해서 드래그하면 됩니다.
26:07 · 그러면 파형이 즉시 변하는 것을 볼 수 있습니다.
26:12 · 그리고 제가 클릭해서 드래그할 때, 드래그를 시작하기 전 파형의 그림자가 뒤에 남겨진다는 점을 주목해 주세요.
26:19 · 덕분에 비교를 할 수 있습니다.
26:21 · 제가 변경한 결과를 즉시 확인할 수 있는 것이죠.
26:25 · 정보 디자인의 두 가지 황금률이 있습니다.
26:27 · 데이터를 보여줄 것, 그리고 비교를 보여줄 것.
26:30 · 제가 여기서 하고 있는 일은 그게 전부입니다.
26:32 · 하지만 이마저도 아주 충분하지는 않습니다.
26:33 · 우리가 여기서 보고 있는 것은 전압입니다.
26:35 · 하지만 전자 공학에는 사실 두 가지 데이터 타입이 있습니다.
26:38 · 전압이 있고, 전류가 있습니다.
26:40 · 그리고 우리가 지금 보지 못하고 있는 것은 이 각각의 부품을 통해 흐르는 전류입니다.
26:44 · 회로를 설계하려면 전압과 전류를 모두 이해해야 합니다.
26:47 · 그 둘 사이의 상호작용을 이해해야 하죠. 아날로그 설계라는 것이 바로 그런 것입니다.
26:52 · 그래서 저는 이것들을 조금 더 넓게 펼친 다음, 이제 이 각각의 부품들을 시간에 따른 전류의 변화 그래프로 대체해 보겠습니다.
27:02 · 이 파란색 상자 하나하나가 부품을 나타냅니다.
27:05 · 구석에 작은 배지, 즉 작은 아이콘이 있어서 이것이 어떤 부품인지 알 수 있습니다.
27:09 · 하지만 이제는 회로에서 일어나는 모든 일을 볼 수 있습니다.
27:14 · 전류가 어떻게 변하는지 볼 수 있습니다.
27:15 · 전압과 전류가 어떻게 변하는지 볼 수 있죠.
27:19 · 숨겨진 것도 없고, 머릿속으로 시뮬레이션할 필요도 없습니다.
27:23 · 즉, 우리는 회로를 표현하는 또 다른 방법을 마주하고 있는 것입니다.
27:28 · 일반적으로 어떤 회로든 이 블록들을 가지고 그릴 수 있지만, 꼬불꼬불한 작은 기호들로 만들어지는 대신 데이터로 만들어지는 것입니다.
27:36 · 그리고 애초에 왜 우리에게 이런 꼬불꼬불한 기호들이 생겨났는지 질문해보는 것이 중요하다고 생각합니다.
27:42 · 그것들이 왜 존재할까요?
27:43 · 종이 위에 연필로 그리기 쉽기 때문에 존재하는 것입니다.
27:47 · 하지만 이건 종이가 아닙니다.
27:49 · 따라서 새로운 매체를 갖게 되었을 때는 이러한 것들을 재고해야 합니다.
27:52 · "이 새로운 매체가 우리가 만드는 것과 어떻게 더 직관적으로 연결되도록 해줄 수 있을까? 이 새로운 매체가 우리가 하는 일을 보면서 작업할 수 있도록 어떻게 도와줄 수 있을까?"를 생각해야 합니다.
28:01 · 프로그래밍의 상황도 이와 완전히 똑같습니다.
28:03 · 컴퓨터 프로그램이란 컴파일러에 넘겨주는 텍스트 정의의 목록이라는 우리의 현재 개념은, 1950년대 후반의 포트란(Fortran)과 알골(Algol)에서 그대로 유래된 것입니다.
28:14 · 그 언어들은 천공 카드(punch cards)를 위해 설계되었습니다.
28:17 · 그래서 카드 더미에 프로그램을 타이핑해서 컴퓨터 오퍼레이터(아래 사진에 있는 사람입니다)에게 건네주고, 나중에 다시 돌아오곤 했죠.
28:26 · 그러니까 그 시절에는 '인터랙티비티(상호작용성)'라는 개념 자체가 없었습니다.
28:29 · 그리고 그 전제가 프로그래밍이 무엇인지에 대한 우리의 현재 관념에 깊이 박혀 있습니다.
28:34 · C 언어는 텔레타이프(teletypes, 전동 타자기)를 위해 설계되었습니다.
28:38 · 저기 위에 있는 사람들이 켄 톰슨(Ken Thompson)과 데니스 리치(Dennis Ritchie)입니다.
28:41 · 리치가 C를 만들었죠.
28:41 · 그리고 이 사진에는 비디오 디스플레이(모니터)가 없습니다.
28:45 · 리치는 기본적으로 자신에게 다시 글자를 타이핑해 주는 고급 타자기에 타이핑을 하고 있는 것입니다.
28:50 · 여러분이 콘솔이나 터미널 창을 사용할 때마다, 여러분은 텔레타이프를 흉내 내고(emulating) 있는 것입니다.
28:56 · 그리고 오늘날에도 사람들은 여전히 REPL이나 대화형 탑 레벨(interactive top level)을 인터랙티브 프로그래밍이라고 생각하는데, 왜냐하면 그것이 텔레타이프에서 할 수 있었던 최선이었기 때문입니다.
29:08 · 마지막으로 보여드리고 싶은 데모가 하나 더 있습니다. 왜냐하면 이 '매체와의 직관적 연결(media connection)'이라는 원칙이 엔지니어링에만 국한된 것이 아니라, 모든 종류의 창작 활동에 관한 것임을 강조하고 싶기 때문입니다.
29:16 · 그러니 완전히 다른 분야로 이동해 보겠습니다.
29:20 · 애니메이션에 대해 생각해 봅시다.
29:21 · 여기 나무와 나뭇잎이 그려진 그림이 하나 있는데, 나뭇잎이 나무에서 아래로 부드럽게 떨어지는 짧은 영상을 만들고 싶다고 해봅시다.
29:33 · 플래시(Flash) 같은 전통적인 애니메이션 패키지에서 이를 수행하는 일반적인 방법은 키프레임(key frames)을 이용하는 것입니다.
29:40 · 기본적으로 서로 다른 시점에 나뭇잎이 어디에 있기를 원하는지 지정한 다음, 재생을 눌러 어떻게 보이는지 확인하는 방식이죠.
29:47 · 그래서 저는 "좋아, 20번째 프레임에 키프레임을 만들고 나뭇잎은 여기에 있어야 해"라고 말합니다.
29:55 · "40번째 프레임에 키프레임을 만들고 나뭇잎은 여기에 있어야 해"라고 지정합니다.
30:01 · 지금 저는 순전히 때려 맞추고 있는 중입니다.
30:02 · 움직임이 보이지 않거든요.
30:04 · 타이밍을 감으로 느낄 수도 없습니다.
30:05 · 그냥 시간과 공간 속에 무작정 요소를 던져 넣고 있는 거죠.
30:08 · 이렇게 각기 다른 시간대에 나뭇잎을 배치해 두었습니다.
30:15 · 이제 트윈(tween) 효과를 추가할 건데요, 플래시(Flash) 프로그램에 이 점들을 연결하라고 명령하는 겁니다.
30:18 · 그러고 나서 재생을 눌러 어떻게 나오는지 보겠습니다.
30:22 · 정말 터무니없어 보이네요.
30:27 · 당구공이 이리저리 튕겨 다니는 것처럼 보입니다.
30:33 · 하지만 사실 제가 원하는 게 뭔지는 저도 대략 알고 있습니다, 그렇죠?
30:38 · 이건 나뭇잎입니다.
30:38 · 저는 나뭇잎이 나무에서 떨어져 아래로 부드럽게 휘날리기를 원합니다.
30:41 · 심지어 제 손으로 나뭇잎이 떨어지는 모습을 이렇게 흉내 낼 수도 있죠.
30:46 · 하지만 플래시는 제 손짓에 귀를 기울일 줄 모릅니다.
30:49 · 하지만 어쩌면 제 손짓에 귀를 기울일 줄 아는 새로운 매체가 있을지도 모릅니다.
30:56 · 그래서 여기서 보여드릴 것은 제가 애니메이션 작업을 위해 만든 작은 앱입니다.
31:02 · 아이패드로 실시간 시연을 할 수 있는 환경이 아니라서, 제가 영상을 만드는 과정을 찍은 영상을 그냥 보여드리겠습니다.
31:08 · 이 장면은 나뭇잎이 나무에서 부드럽게 떨어지고, 화면이 옆으로 이동(팬)하면 토끼가 무언가를 하는 식으로 전개될 것입니다.
31:18 · 그리고 두 가지 특징이 있습니다.
31:21 · 첫째, 이 작업은 꽤 빠르게 진행될 겁니다.
31:23 · 둘째, 저는 거의 내내 양손을 사용할 것입니다.
31:29 · 여기 배경, 전경 같은 여러 레이어가 있는데, 왼손 엄지손가락으로 어떤 레이어를 움직일지 선택합니다.
31:34 · 나뭇잎을 제 위치로 옮기고, 토끼를 화면 밖으로 치운 뒤 시간을 흐르게 합니다.
31:42 · 이제 나뭇잎이 나무에서 휘날리며 떨어지는 모습을 (손짓으로) 연기해 보겠습니다.
31:46 · 뒤로 돌려서 어떻게 나왔는지 확인해 보죠.
31:52 · 움직임은 꽤 괜찮아 보이지만, 나뭇잎이 앞뒤로 좌우로 흔들릴 필요가 있겠네요.
31:55 · 그래서 회전 컨트롤러를 꺼내서, 다시 뒤로 돌려 나뭇잎이 떨어지기 직전의 위치를 찾은 뒤 회전을 녹화합니다.
32:05 · 그리고 방금 살짝 뒤집히는 효과를 넣었는데, 그 순간 그게 자연스럽게 느껴졌기 때문입니다.
32:07 · 계획에 없던 거였죠.
32:09 · 잠시 멈추겠습니다. 화면을 옆으로 넘겨야 하니 여러 레이어를 한 번에 드래그해야 하니까요.
32:13 · 모든 레이어를 리스트로 묶어 잡습니다.
32:14 · 배경 레이어의 민감도를 낮춰서, 일종의 시차(패럴랙스) 효과를 위해 배경이 더 느리게 움직이도록 합니다.
32:18 · 가로로만 움직이고 싶으니 가로 드래그 툴을 꺼내서 어떻게 보이는지 확인합니다.
32:23 · 시차 효과가 아주 마음에 들지는 않아서 민감도를 조금 조절하고 다시 시도해 봅니다.
32:29 · 이게 더 낫네요.
32:31 · 이제 준비가 되었습니다.
32:33 · 작품의 리듬을 다시 타기 위해 처음으로 되돌립니다.
32:40 · 나뭇잎이 떨어집니다.
32:42 · 잠시 한 박자 쉬고,
32:43 · 화면을 넘기기 시작합니다.
32:45 · 제가 몇 프레임을 기다렸는지는 모릅니다.
32:46 · 시간이 얼마나 흘렀는지도 모릅니다.
32:48 · 그냥 딱 맞는 느낌이 들었을 때 움직인 것입니다.
32:51 · 이렇게 이 겨울 장면으로 화면을 넘긴 다음 속도를 줄여서 멈춥니다.
32:54 · 그런 다음 다시 뒤로 돌립니다. 토끼한테 무언가를 시키고 싶거든요.
32:58 · 썼던 도구들은 다 썼으니 던져 버립니다.
33:01 · 그리고 토끼가 움직여야겠다고 생각되는 순간까지 기다렸다가, 토끼가 깡충 뛰어 도망치게 합니다.
33:08 · 토끼의 자세가 몇 가지 있어서 그걸 꺼내 놓았습니다.
33:12 · 그리고 토끼가 땅에서 뛰어오르기 직전의 타이밍을 찾습니다. 바로 저기네요.
33:20 · 포즈를 바꾸고, 토끼가 뛰어 도망갈 때 포즈를 번갈아 전환해 줍니다.
33:25 · 그러고 나서 어떻게 만들어졌는지 확인하기 위해 다시 뒤로 돌려 전체 화면으로 띄워 드리겠습니다.
33:30 · 완성된 작품입니다.
33:33 · 악기를 연주하듯 제 손으로 연기하며, 단 2분 만에 이 영상을 만들었습니다.
33:54 · 저 자신과 제가 만들고자 하는 것 사이에 매우 즉각적인 연결이 이루어진 것입니다.
33:59 · (박수) 이 도구를 만들게 된 영감 중 하나는 제가 몇 년 전에 만들려고 시도했던 애니메이션이었습니다.
34:14 · 저 작품은 아니지만, 그것 역시 나무에서 나뭇잎이 떨어지는 장면으로 시작했죠.
34:18 · 그리고 저는 그 나뭇잎의 키프레임을 잡으려고 플래시 프로그램과 씨름하며 온종일 보냈습니다.
34:23 · 만들 수는 있었습니다.
34:25 · 하지만 그게 끝이었습니다. (지쳐서 포기했죠.)
34:27 · 저에게는 여전히 스토리보드가 있습니다.
34:29 · 가끔 그 작품을 위해 썼던 음악을 연주해보기도 하지만, 작품 자체는 제 머릿속에 갇혀 있습니다.
34:35 · 그래서 저는 항상 수많은 사람들의 머릿속에 갇혀 있을 수천만 개의 작품을 생각합니다.
34:43 · 단지 애니메이션이나 예술뿐만 아니라, 온갖 종류의 아이디어들을 말이죠.
34:49 · 극도로 중요한 아이디어, 세상을 바꿀 발명품, 생명을 살릴 과학적 발견 등 온갖 아이디어가 포함됩니다. 이 모든 것들은 자라나야 하는 아이디어들입니다.
35:01 · 하지만 아이디어가 자랄 수 있는 환경, 창작자가 이러한 '즉각적인 연결'을 통해 아이디어를 키워낼 수 있는 환경이 없다면, 이러한 아이디어 중 상당수는 세상에 나오지 못할 것입니다.
35:09 · 혹은 불완전한 상태로 나오게 되겠죠.
35:13 · 그래서 저는 '창작자에게는 즉각적인 연결이 필요하다'는 원칙을 가지고 있습니다.
35:17 · 그리고 방금 보여드린 모든 시연은 단순히 제가 주변을 둘러보며 그 원칙이 무너지고 있는 곳을 발견하고, 이를 해결하려고 노력한 결과물입니다.
35:28 · 제가 한 일은 정말 그게 전부입니다.
35:30 · 저는 그저 이 이정표 같은 원칙을 따랐을 뿐이고, 그 원칙이 제가 해야 할 일로 저를 인도했습니다.
35:36 · 하지만 이 이야기에서 가장 중요한 부분인 '왜(Why)'에 대해서는 아직 많은 말을 하지 않았습니다.
35:45 · 왜 제가 이 원칙을 가지고 있는지, 왜 이 일을 하는지 말이죠.
35:52 · 저는 이 원칙이 위배되는 상황을 볼 때, 그것을 기회라고 생각하지 않습니다.
35:59 · 창작자들이 도구의 한계에 부딪혀 제약을 받고 그들의 아이디어가 타협당하는 것을 볼 때, 저는 "오, 좋아. 제품을 만들 기회네, 사업을 시작할 기회야, 혹은 연구를 하거나 이 분야에 기여할 기회군"이라고 말하지 않습니다.
36:13 · 해결할 문제를 찾았다고 해서 신이 나지도 않습니다. 무언가를 만드는 즐거움 때문에 이 일을 하는 것도 아닙니다.
36:18 · 아이디어는 저에게 매우 소중합니다.
36:21 · 그래서 아이디어가 죽어가는 것을 보면 마음이 아픕니다.
36:26 · 비극을 보는 것 같습니다.
36:29 · 저에게 그것은 도덕적인 잘못처럼 느껴집니다.
36:33 · 불의(不義)처럼 느껴집니다.
36:34 · 그리고 만약 제가 그것에 대해 할 수 있는 일이 있다고 생각되면, 그렇게 하는 것이 저의 '책임'이라고 느낍니다.
36:40 · 기회가 아니라, 책임인 것이죠.
36:43 · 이것은 단지 저만의 신념입니다. 여러분에게 저처럼 이것을 믿으라고 강요하는 것은 아닙니다.
36:47 · 제가 여기서 드리고 싶은 말씀은 불의, 책임, 도덕적 잘못과 같이 제가 사용하는 이 단어들이 우리가 보통 기술 분야에서 듣는 단어들이 아니라는 점입니다.
37:01 · 우리는 보통 사회적 대의와 관련된 상황에서 이런 단어들을 듣습니다.
37:04 · 검열, 성차별, 환경 파괴 같은 것들 말이죠. 우리는 이 모든 것을 도덕적 잘못으로 인식합니다.
37:15 · 우리 중 대부분은 시민권 침해 현장을 목격하고 "오, 좋아, 기회다"라고 생각하지 않을 것입니다.
37:20 · 아니길 바랍니다.
37:21 · 대신, 우리는 역사 속에서 이러한 사회적 잘못을 인식하고 이를 해결하는 것을 자신의 책임으로 여긴 사람들을 가졌던 큰 행운을 누렸습니다.
37:32 · 그래서 자신이 믿는 대의를 위해 싸우는 데 평생을 바치는 '활동가(Activist)의 삶'이라는 것이 존재합니다.
37:41 · 그리고 이 강연의 목적은 이러한 활동가의 삶이 비단 사회 운동에만 국한된 것이 아님을 말씀드리기 위함입니다.
37:48 · 기술자로서 여러분도 세상의 잘못을 인식할 수 있습니다.
37:53 · 더 나은 세상이 어떤 모습일지에 대한 비전을 가질 수 있고, 하나의 원칙을 위해 싸우는 데 자신을 헌신할 수 있습니다.
38:00 · 활동가들은 보통 조직을 결성하여 싸우지만, 여러분은 '발명'을 통해 싸울 수 있습니다.
38:07 · 이제 이렇게 살아온 다른 몇몇 사람들에 대해 말씀드리고자 합니다. 래리 테슬러(Larry Tesler)부터 시작하죠. 래리는 그의 인생에서 많은 훌륭한 일들을 해냈지만, 제가 말씀드릴 작업은 그가 70년대 중반 제록스 파크(Xerox PARC)에서 했던 일입니다. 당시에는 개인용 컴퓨터라는 개념이 존재하지 않았습니다. 개인용 컴퓨팅이라는 개념은 매우 초기 단계였죠. 래리와 파크의 동료들은 그것이 세상을 바꿀 잠재력을 가지고 있으며, 개인용 컴퓨팅이 사람들의 생각과 삶의 방식을 바꿀 수 있을 것이라 느꼈습니다.
38:39 · 그리고 이 방에 계신 우리 모두는 그들의 생각이 맞았다는 것에 동의할 것입니다.
38:43 · 하지만 당시에 소프트웨어 인터페이스는 '모드(Mode)'를 중심으로 설계되었습니다.
38:49 · 예컨대 텍스트 에디터에서 타자기처럼 그냥 글자를 입력한다고 화면에 글자가 나타나는 것이 아니었습니다.
38:56 · 기본적으로 '명령 모드' 상태에 있었죠.
38:57 · 텍스트를 삽입하고 싶다면 I를 눌러 '삽입 모드'로 들어간 다음, 다시 ESC를 눌러 '명령 모드'로 빠져나와야 했습니다.
39:02 · 혹은 A를 눌러 '추가 모드'로 들어가야 했을 수도 있죠.
39:04 · 텍스트를 이동시키고 싶다면 M을 눌러 '이동 모드'로 들어가고, 요소를 선택하고 이동시키기 위한 모드 안에 머물러야 했습니다.
39:10 · 래리는 사람들이 컴퓨터를 사용하는 모습을 관찰하곤 했습니다.
39:16 · 사실 래리는 소프트웨어 사용자 조사(User Studies)라는 개념을 개척한 인물이기도 합니다. 그가 한 또 다른 업적이죠.
39:20 · 아무튼 그는 사람들이 소프트웨어를 사용하는 모습을 지켜보았고, 많은 사람이 교육을 받고 몇 주 동안 사용한 후에도 컴퓨터를 편안하게 느끼지 못한다는 것을 발견했습니다.
39:31 · 그리고 그는 이 모든 원인이 바로 '모드'에 있다고 믿었습니다. 모드가 주는 복잡성이 많은 사람이 넘지 못하는 일종의 장벽이 되었던 것이죠.
39:41 · 그래서 이것은 개인용 컴퓨팅이 꿈꾸던 미래에 대한 일종의 위협이 되었습니다.
39:50 · 그리하여 래리는 소프트웨어에서 모드를 제거하는 것을 자신의 개인적 사명으로 삼았습니다.
39:53 · 그리고 그는 원칙을 세웠습니다. 그 누구도 모드 안에 갇혀서는 안 된다는 것이었죠.
39:54 · 그가 항상 외치고 다니던 슬로건은 "나를 모드 안에 가두지 마라(Don't mode me in)"였고, 이를 티셔츠에 인쇄해 입고 다니기도 했습니다. 이 원칙은 그가 한 모든 작업에 영감을 주었습니다. 그는 자신이 하는 모든 작업에서 이 원칙을 생각했고, 결국 오늘날 우리가 아는 형태의 텍스트 편집 방식을 도입한 '지프시(Gypsy)'라는 텍스트 에디터를 만들어 냈습니다.
50:07 · 그리고 그 일이 바로 일어나지는 않을 수도 있습니다.
50:09 · 원칙을 찾는 데는 시간이 걸릴 수 있습니다. 원칙을 찾는다는 것은 본질적으로 일종의 '자기 발견' 과정이기 때문입니다.
50:14 · 자신의 인생이 무엇을 위한 것이어야 하는지, 한 인간으로서 무엇을 옹호하고 대변하고 싶은지 알아내려고 노력하는 과정 말이죠.
50:21 · 저의 경우, 제 원칙에 대한 진정한 이해가 확고해지기까지 약 10년이라는 세월이 걸렸습니다.
50:28 · 바로 제 20대 시절이었습니다.
50:30 · 젊었을 때는 이런 방식으로 살아야 한다고 느꼈지만, 저에게 중요한 것이 무엇인지 아주 희미한 불빛만 보였을 뿐 전체적인 그림은 보이지 않았습니다.
50:38 · 정말 불확실했고, 이는 제게 큰 괴로움이었습니다.
50:41 · 제가 해야 했던 일은 그저 많은 일을 해보는 것뿐이었습니다.
50:44 · 수많은 것을 만들고, 다양한 종류의 것을 만들고, 많은 것을 공부하고, 아주 많은 것을 경험하면서, 이 모든 경험을 나 자신을 분석하는 도구로 삼는 것이었죠.
50:56 · 이 모든 경험을 겪으며 스스로에게 물었습니다. '이게 내 마음에 깊은 울림을 주나?'
51:00 · '이건 나를 밀어내나(거부감이 드나)?'
51:01 · '아니면 아무 관심도 없나?'
51:02 · 왠지 모르게 강렬한 감정이 들었던 경험들의 말뭉치(corpus)를 쌓아 올리고, 그것들을 이해하려 노력하며 왜 그런지 이유를 알아내려 했습니다.
51:10 · '내가 이렇게 강렬하게 반응하는 이 모든 경험 속에 숨겨진 비밀 공식(비결)은 대체 무엇일까?' 하고 말이죠.
51:14 · 사람마다 다 다르다고 생각합니다.
51:17 · 제가 언급했던 그 위대한 인물들도 저마다의 시작 이야기(탄생 설화)를 가지고 있고, 그것은 찾아 읽어보실 수 있습니다.
51:21 · 다만 제가 드리고 싶은 말씀은, 자신을 단 하나의 기술을 연마하는 데만 가두어 두면 넓은 범위의 경험을 얻기 어려워질 수 있다는 점입니다. 이런 종류의 일을 해나가는 데 있어 넓은 경험은 너무나 소중해 보이는데도 말이죠.
51:32 · 그리고 마지막으로, 만약 여러분이 어떤 원칙을 따르기로 선택한다면, 그 원칙은 그저 여러분이 믿는 진부하고 평범한 생각이어서는 안 됩니다. 많은 사람이 소프트웨어를 더 사용하기 쉽게 만들고 싶다거나, 사용자에게 감동을 주고 싶다거나, 단순하게 만들고 싶다고 말하는 것을 들으실 겁니다. 특히 '단순함(simple)'은 요즘 아주 핫하죠. 모두가 단순하게 만들고 싶어 합니다. 물론 좋은 생각입니다. 그것들이 약간의 방향성을 제시해 줄 수는 있겠지만, 직접적인 행동으로 옮기기에는 너무나 모호합니다. 래리 테슬러도 단순함을 좋아했지만, 그의 원칙은 이토록 구체적인 통찰의 알맹이였습니다. 바로 "어떤 사람도 모드에 갇혀서는 안 된다"는 것이었죠.
52:07 · 그리고 그것은 강력한 원칙이었습니다. 세상을 바라보는 새로운 시각을 제공해 주었기 때문입니다. 그 원칙은 세상을 상당히 객관적인 방식으로 옳고 그름으로 나누어 주었습니다. 덕분에 그는 누군가 텍스트를 선택하는 모습을 보며 "이 사람이 지금 모드에 갇혀 있는가, 아닌가?"를 물을 수 있었습니다. 만약 그렇다면(Yes), 그는 그 문제를 해결하기 위해 무언가를 해야만 했던 것이죠.
52:30 · 마찬가지로 저 역시 "창작자들에게는 강력한 도구가 필요하다"고 믿습니다.
52:33 · 하지만 이건 사실 저를 어디로도 인도해 주지 못하는 막연하고 좋은 생각일 뿐입니다.
52:38 · 저의 원칙은 "창작자들에게는 (도구와의) 즉각적인 연결이 필요하다"는 것입니다.
52:42 · 따라서 저는 여러분이 코드 한 줄을 바꾸는 모습을 지켜보며 물을 수 있습니다. "그 변화의 효과를 즉시 확인했는가, 아닌가?"
52:47 · 확인했다(Yes)인가요, 아니면 아니다(No)인가요?
52:49 · 아니라면(No), 저는 그 문제를 해결하기 위해 무언가를 해야 합니다.
52:52 · 다시 말씀드리지만, 제가 보여드렸던 그 모든 데모(시연)는 제가 그렇게 행동함으로써 나온 것들입니다.
52:58 · 제가 이 원칙을 따르고, 그 원칙이 제가 정확히 무엇을 해야 하는지 이끌어주도록 내버려 둔 결과물이죠.
53:03 · 이처럼 여러분이 구체적인 통찰이 담긴 원칙의 안내를 받는다면, 그 원칙이 여러분을 이끌어 줄 것입니다.
53:09 · 그리고 여러분이 지금 하고 있는 일이 옳은지 그른지 언제나 알 수 있을 것입니다.
53:12 · 인생을 살아가는 데는 수많은 방법이 있습니다.
53:21 · 아마도 인생에서 깨달을 수 있는 가장 중요한 사실은, 여러분 삶의 모든 측면이 결국 '선택'이라는 점일 것입니다.
53:27 · 우리가 기본적으로 주어지는 선택지(기본값)를 따를 때, 여러분은 그저 삶을 몽유병 환자처럼 걸어가며 자신 앞에 놓인 길을 그대로 받아들이는 쪽을 선택할 수도 있습니다.
53:36 · 세상을 있는 그대로 받아들이는 쪽을 선택할 수도 있죠. 하지만 꼭 그럴 필요는 없습니다.
53:41 · 만약 세상에 무언가 잘못되었다고 느껴지는 것이 있고, 더 나은 세상이 어떤 모습일지에 대한 비전이 있다면, 여러분은 자신만의 길잡이가 될 원칙을 찾아 대의를 위해 싸울 수 있습니다.
53:56 · 그러니 이 강연이 끝난 후, 잠시 시간을 내어 자신에게 무엇이 정말 중요한지, 자신이 무엇을 믿고 있으며, 무엇을 위해 싸울 수 있을지 생각해 보셨으면 좋겠습니다.
54:05 · 감사합니다.